package com.cntaiping.workutil.videoanalysis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 全局异常处理
 *
 * @author HuoShengyu
 * @date 2018-05-26 16:17:32
 * @version 1.0
 */
//@RefreshScope
@RestController
@RestControllerAdvice
@EnableConfigurationProperties(ServerProperties.class)
public class GlobalExceptionHandler extends AbstractErrorController {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	private final ServerProperties serverProperties;

	@Autowired
	public GlobalExceptionHandler(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
		super(errorAttributes);
		this.serverProperties = serverProperties;
	}

	/**
	 * 处理Exception异常
	 *
	 * @param e
	 *          异常信息
	 * @return Response
	 */
	@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
	@ExceptionHandler(value = Exception.class)
	public Response defaultHandler(Exception e) {
		logger.info("错误信息: " + e.getMessage());
		e.printStackTrace();
		return Response.error(ErrorCode.SYSTEM_NORMAL_EXCEPTION.getCode(),ErrorCode.SYSTEM_NORMAL_EXCEPTION.getMessage());
	}

	/**
	 * 处理BindException异常
	 *
	 * @param e
	 *          异常信息
	 * @return Response
	 */
	@ExceptionHandler(value = { BindException.class, MethodArgumentNotValidException.class})
	public Response validatedHandler(Exception e) {
		List<ObjectError> errors = new ArrayList<ObjectError>();
		if (e instanceof BindException) {
			errors = ((BindException) e).getAllErrors();
		} else if (e instanceof MethodArgumentNotValidException) {
			errors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
		}
		StringBuilder sb = new StringBuilder("入参校验失败: ");
		for (int i = 0; i < errors.size(); i++) {
			ObjectError error = errors.get(i);
			sb.append("\n").append(i + 1).append(")");
			sb.append(error.getDefaultMessage());
		}
		logger.info("入参信息校验异常: "+ sb.toString());
		e.printStackTrace();
		return Response.error("9999",sb.toString());
	}

	@ExceptionHandler(value = ConstraintViolationException.class)
	@ResponseStatus(code = HttpStatus.BAD_REQUEST)
	public Response ConstraintViolationHandler(ConstraintViolationException e){
		Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
		String message = constraintViolations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));

		return Response.error("9999",message);

	}
	@ExceptionHandler(value = ErrorException.class)
	@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
	public Response RuntimeExceptionHandler(ErrorException e){
		logger.error("请求执行异常 code:[{}],message: {}",e.getErrorCode(),e.getMessage());
		e.printStackTrace();

		return Response.error(e.getErrorCode(),e.getMessage());

	}



	@Override
	public String getErrorPath() {
		return serverProperties.getError().getPath();
	}

	/**
	 * 请求路径异常
	 *
	 * @param request
	 *                请求
	 * @return Response
	 */
}
